﻿. .\Import-MyModule.ps1
. .\Change-Cscfg.ps1
. .\ConfigurationVariables.ps1
. .\Create-InstallJob.ps1
. .\Wait-DeploymentStabilized.ps1
. .\Validation.ps1
. .\Utils.ps1

# Import the 'CloudBlitz.Powershell' cmdlet; does it only if not imported yet
Import-MyModule -Name "CloudBlitz.Powershell" -Path $cmdletsPath
$hpcTypesPath = [System.IO.Path]::GetDirectoryName($cmdletsPath) + "\HpcSchedulerManagement.dll"
Add-Type -Path $hpcTypesPath -ErrorAction Stop

if (!(ValidateDeployment))
{
	Write-Host "Please fix all errors and start deployment again."
	Break
}

######################### MAKE SURE TO RUN InstallAndExportCertificate.ps1 BEFORE RUNNING THIS #######################
######################################################################################################################
$mgmtCert = get-childitem Cert:\CurrentUser\My\ | Where-Object {$_.Subject -eq "CN="+$certificateCn} -ErrorAction Stop
if ($mgmtCert -eq $null)
{
    Write-Error "Make sure you installed certificate `"$certificateCn`" and run deployment script again."
    Break
}

$certificatePfx = ".\" + $certificateFileNameRoot + ".pfx"

$subscription = $null
try
{
	$subscription = Get-AzureSubscription -SubscriptionName $SubscriptionName -ErrorAction SilentlyContinue
}
catch [System.ArgumentException]
{
    if ($Error[0].Exception.Message.Contains("No certificate was found in the certificate store"))
    {
        # Cleaning up previous subscription settings
        Get-Item ($env:APPDATA + "\Windows Azure Powershell\config.json") | Remove-Item -ErrorAction SilentlyContinue
        Get-Item ($env:APPDATA + "\Windows Azure Powershell\DefaultSubscriptionData.xml") | Remove-Item -ErrorAction SilentlyContinue
        Get-Item ($env:APPDATA + "\Windows Azure Powershell\publishSettings.xml") | Remove-Item -ErrorAction SilentlyContinue        
    }
}

$restoreSubscription = $false
if (($subscription -eq $null) -or ($subscription.SubscriptionName -ne $SubscriptionName) -or
    ($subscription.Certificate.Thumbprint -ne $mgmtCert.Thumbprint) -or
    ($subscription.SubscriptionId -ne $SubscriptionId))
{
    if ($subscription -ne $null)
    {
        $restoreSubscription = $true
        $previousSubscriptionName = $subscription.SubscriptionName
        $previousSubscriptionId = $subscription.SubscriptionId
        $previousSubscriptionCert = $subscription.Certificate
    }

    Set-AzureSubscription -SubscriptionName $SubscriptionName -Certificate $mgmtCert -SubscriptionId $SubscriptionId -ErrorAction Stop
    Set-AzureSubscription -DefaultSubscription $SubscriptionName -ErrorAction Stop
    Write-Host "Set the default subscription"
}

Write-Host "Retrieving storage account $deploymentName"
try
{
	$cloudBlitzStore = Get-AzureStorageAccount -StorageAccountName $deploymentName -ErrorAction Stop
}
catch [System.Exception]
{
     Write-Host "Storage account $deploymentName not found, creating new."
}

if ($null -eq $cloudBlitzStore)
{   
    Write-Host "Storage account $deploymentName not found, creating new."
    New-AzureStorageAccount -StorageAccountName $deploymentName -Location $deployLocation -Description "CloudBlitz storage account" -Label $runLabel -ErrorAction Stop
    $cloudBlitzStore = AzureStorageAccount -StorageAccountName $deploymentName
    Write-Host "Created the deployment store $deploymentName"
}
Set-AzureSubscription -SubscriptionName $SubscriptionName -CurrentStorageAccount $deploymentName -ErrorAction Stop

Write-Host "Retrieving storage account keys."
$storageAccountKeys = Get-AzureStorageKey -StorageAccountName $deploymentName -ErrorAction Stop

Write-Host "Uploading packages."
hpcpack upload $((Get-Item "$deployRolePackage").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$deploymentContainer /blobtype:BlockBlob
hpcpack upload $((Get-Item "$clusterTemplatePackage").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$deploymentContainer /blobtype:BlockBlob
hpcpack upload $((Get-Item "$clusterTemplateCsCfg").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$deploymentContainer /blobtype:BlockBlob
hpcpack upload $((Get-Item "$clusterTemplateCsdef").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$deploymentContainer /blobtype:BlockBlob
hpcpack upload $((Get-Item "$startupCmd").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$installContainer /blobtype:BlockBlob
hpcpack upload $((Get-Item "$installScript").FullName) /account:$deploymentName /key:$($storageAccountKeys.Primary) /container:$installContainer /blobtype:BlockBlob
Write-Host "Copied packages."

# Deploy deployer role
Write-Host "Changing the CloudBlitz deployment role configuration."    
$deployRoleCsCfgFullName = (Get-Item "$deployRoleCsCfg").FullName
Change-Csfg -fileName $deployRoleCsCfgFullName -connString "CloudBlitz.Storage" -UseSsl $true -AccountName $cloudBlitzStore.StorageAccountName -AccountKey $storageAccountKeys.Primary
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterTemplatePackage" -value (GetBlobAbsoluteUri $deploymentName $deploymentContainer $clusterTemplatePackage)
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterTemplateCsdef" -value (GetBlobAbsoluteUri $deploymentName $deploymentContainer $clusterTemplateCsdef)
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterTemplateCscfg" -value (GetBlobAbsoluteUri $deploymentName $deploymentContainer $clusterTemplateCsCfg)
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterDnsName" -value $deploymentName
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterAdminLogin" -value $administratorName
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ClusterAdminPassword" -value $systemPassword
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.HeadNodeInstanceCount" -value $HeadNodeInstanceCount
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ComputeNodeInstanceCount" -value $ComputeNodeInstanceCount
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.SubscriptionId" -value $SubscriptionId
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.Location" -value $deployLocation
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ManagementCertThumbprint" -value $mgmtCert.Thumbprint

$certificateBytes = Get-Content $certificatePfx -Encoding Byte
Change-Csfg -fileName $deployRoleCsCfgFullName -config "CloudBlitz.ServiceCertificate" -value $([System.Convert]::ToBase64String($certificateBytes))

Change-Csfg -fileName $deployRoleCsCfgFullName -connString "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" -UseSsl $true -AccountName $cloudBlitzStore.StorageAccountName -AccountKey $storageAccountKeys.Primary
Change-Csfg -fileName $deployRoleCsCfgFullName -certificate "Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" -value $mgmtCert.Thumbprint
Change-Csfg -fileName $deployRoleCsCfgFullName -certificate "CloudBlitz.ManagementCertificate" -value $mgmtCert.Thumbprint
Write-Host "Changed the CloudBlitz deployment role configuration."

$continue = $false
if ((Test-AzureName -Service -Name $deployerServiceName) -or (Test-AzureName -Service -Name $deploymentName))
{
    if ($removePreviousDeploymentAndService)
    {
        Write-Host "Removing previous hosted service and deployment"
        $deployer = Get-AzureDeployment -ServiceName $deployerServiceName -Slot Production
        if ($deployer)
        {
            Write-Host "Removing previous deployment"
            Remove-AzureDeployment -ServiceName $deployerServiceName -Slot Production -Force 

			# Remove the cloud service that was hosting the deployment
			Write-Host "Removing previous hosted service"
			Remove-AzureService -ServiceName $deployerServiceName -Force
        }

        $service = Get-AzureDeployment -ServiceName $deploymentName -Slot Production
        if ($service)
        {
            Write-Host "Removing previous hosted service"
            Remove-AzureDeployment -ServiceName $deploymentName -Slot Production -Force

			# Remove the cloud service that was hosting the deployment
			Remove-AzureService -ServiceName $deploymentName -Force
        }

        $continue = $true
    }
    else
    {
        Write-Host "Cannot complete deployment, please make sure no services with names $deploymentName and $deployerServiceName exist."
    }
}
else
{
    $continue = $true
}

if ($continue)
{
    $deployPackageBlob = GetBlobAbsoluteUri $deploymentName $deploymentContainer $deployRolePackage

    Write-Host "Deploying the deployer role."
    New-AzureService -ServiceName $deployerServiceName -Location $deployLocation -ErrorAction Stop
    
    Add-AzureCertificate -ServiceName $deployerServiceName -CertToDeploy $certificatePfx -Password $systemPassword -ErrorAction Stop
    New-AzureDeployment -ServiceName $deployerServiceName -Slot Production -Package $deployPackageBlob -Configuration $deployRoleCsCfgFullName -Label $runLabel -ErrorAction Stop
    Write-Host "Deployed the deployer role"
	
	$deployment = Get-AzureDeployment -ServiceName $deployerServiceName -Slot Production

	Write-Host "Waiting deployer $($deployment.DeploymentId) to deploy HPC cluster"
	$deploymentState = Wait-DeploymentStabilized -StorageAccountName $deploymentName -StorageAccountKey $storageAccountKeys.Primary -DeploymentId $deployment.DeploymentId

    if ($deploymentState -eq "Finished")
    {
		ipconfig /flushdns
        Write-Host "HPC cluster deployment stabilized, creating install job"
        Create-InstallJob -ClusterName $deploymentName -AdminLogin $administratorName -AdminPassword $systemPassword -CertificateThumbprint $mgmtCert.Thumbprint -StorageAccountName $deploymentName -StorageAccountKey $storageAccountKeys.Primary -InstallContainer $installContainer
    }
    
    Write-Host "Removing the deployer"
    Remove-AzureDeployment -ServiceName $deployerServiceName -Slot Production -Force
    Remove-AzureService -ServiceName $deployerServiceName -Force
}

if ($restoreSubscription)
{
    Write-Host "Restoring Azure Subscription"

    Set-AzureSubscription -SubscriptionName $previousSubscriptionName -Certificate $previousSubscriptionCert -SubscriptionId $previousSubscriptionId -ErrorAction Stop
    Set-AzureSubscription -DefaultSubscription $previousSubscriptionName -ErrorAction Stop
}


Write-Host "Ending script"